﻿using Manon.Admin.Web.Application.Dtos.Role;
using Manon.Admin.Web.Domain.Entities;
using Manon.Admin.Web.Domain.Repositories;
using Manon.Core;
using Manon.Core.Commons;
using Manon.Core.Extensions;
using Manon.Repository;
using Manon.Repository.Collections;
using Microsoft.EntityFrameworkCore;

namespace Manon.Admin.Web.Application.Impl
{
    public class RoleService : IRoleService
    {

        private readonly ILogger<RoleService> _logger;
        private readonly IUnitOfWork _unitOfWork;
        private readonly IApplicationUser _applicationUser;

        private readonly IRolesRepository _rolesRepository;
        private readonly IUserRolesRepository _userRolesRepository;
        private readonly IRoleMenusRepository _rolesMenusRepository;
        public RoleService(ILogger<RoleService> logger,
            IUnitOfWork unitOfWork,
            IApplicationUser applicationUser,
            IRolesRepository rolesRepository,
            IUserRolesRepository userRolesRepository,
            IRoleMenusRepository rolesMenusRepository
            )
        {
            _logger = logger;
            _unitOfWork = unitOfWork;
            _applicationUser = applicationUser;
            _rolesRepository = rolesRepository;
            _userRolesRepository = userRolesRepository;
            _rolesMenusRepository = rolesMenusRepository;
        }


        /// <summary>
        /// 获取角色分页列表
        /// </summary>
        /// <param name="Input"></param>
        /// <returns></returns>
        public async Task<PagedList<RoleOutput>> GetRolePageList(GetRolePageListInput Input)
        {
            try
            {

                var result = await _rolesRepository
                    .GetQuery()
                    .WhereIf(!string.IsNullOrEmpty(Input.RoleName), e => e.RoleName.Contains(Input.RoleName))
                    .WhereIf(Input.Enabled.HasValue, e => e.Enabled == Input.Enabled.Value)
                    .ToPagedListAsync<RoleOutput, Roles>(Input);
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError("获取角色分页列表异常", ex);
                throw;
            }
        }


        /// <summary>
        /// 获取角色信息
        /// </summary>
        /// <param name="Input"></param>
        /// <returns></returns>
        public async Task<RoleOutput> GetRoleById(int roleId)
        {
            if (roleId == 0) return new RoleOutput() { Enabled = true };

            try
            {
                var result = await _rolesRepository.GetFirstOrDefaultAsync(x => x.Id == roleId);
                return result.ConvertTo<Roles, RoleOutput>();
            }
            catch (Exception ex)
            {
                _logger.LogError("获取角色信息异常", ex);
                throw;
            }
        }

        /// <summary>
        /// 保存角色信息
        /// </summary>
        /// <param name="Input"></param>
        /// <returns></returns>
        public async Task<Result> SaveRole(SaveRoleInput Input)
        {
            try
            {
                var result = await _rolesRepository.GetFirstOrDefaultAsync(x => x.Id == Input.Id);
                if (result == null)
                {
                    result = new Roles();
                    result.CreateTime = DateTime.Now;
                    result.Enabled = true;
                    result.UpdateTime = DateTime.Now;
                    result.RoleName = Input.RoleName;
                    result.OrderIndex = Input.OrderIndex;
                    result.Remark = Input.Remark;
                    result.RoleCode = Input.RoleCode;
                    result.CreateBy = _applicationUser.UserId;
                    result.UpdateBy = _applicationUser.UserId;
                    await _rolesRepository.InsertAsync(result);
                }
                else
                {
                    result.Enabled = Input.Enabled;
                    result.UpdateTime = DateTime.Now;
                    result.RoleName = Input.RoleName;
                    result.OrderIndex = Input.OrderIndex;
                    result.Remark = Input.Remark;
                    result.RoleCode = Input.RoleCode;
                    result.UpdateBy = _applicationUser.UserId;
                    await _rolesRepository.UpdateAsync(result);
                }
                await _unitOfWork.SaveChangesAsync();
                return Result.Successed("保存成功!");
            }
            catch (Exception ex)
            {
                _logger.LogError("保存角色信息异常", ex);
                throw;
            }
        }


        /// <summary>
        /// 设置角色是否可用
        /// </summary>
        /// <param name="Input"></param>
        /// <returns></returns>
        public async Task<Result> SetEnabled(SetRoleEnabledInput Input)
        {
            try
            {
                var role = await _rolesRepository.GetFirstOrDefaultAsync(x => x.Id == Input.RoleId);

                if (role == null) return null;
                role.Enabled = Input.Enabled;
                await _rolesRepository.UpdateAsync(role);
                await _unitOfWork.SaveChangesAsync();
                return Result.Successed("设置成功!");

            }
            catch (Exception ex)
            {
                _logger.LogError("设置角色是否可用异常", ex);
                throw;
            }
        }


        /// <summary>
        /// 获取角色简要信息列表
        /// </summary>
        /// <returns></returns>
        public async Task<List<SimpleRoleOutput>> GetSimpleRoleListAsync()
        {
            try
            {
                List<SimpleRoleOutput> list = new List<SimpleRoleOutput>();


                var result = await _rolesRepository.GetQuery().OrderBy(n => n.OrderIndex).ThenBy(n => n.Id).ToListAsync();
                if (result == null)
                {
                    return list;
                }

                foreach (var item in result)
                {
                    list.Add(new SimpleRoleOutput()
                    {
                        RoleId = item.Id.ToString(),
                        RoleName = item.RoleName,
                        Enabled = item.Enabled
                    });
                }
                return list;


            }
            catch (Exception ex)
            {
                _logger.LogError("获取环境变量列表异常", ex);
                throw;
            }
        }

        /// <summary>
        /// 保存用户角色
        /// </summary>
        /// <param name="Input"></param>
        /// <returns></returns>
        public async Task<Result> BandRoles(BandRoleInput Input)
        {
            try
            {


                var existsRoles = await _userRolesRepository.GetListAsync(n => n.UserId == Input.UserId);
                await _userRolesRepository.DeleteAsync(existsRoles);

                List<UserRoles> listUserRoles = new List<UserRoles>();

                if (Input.RoleIds != null && Input.RoleIds.Count != 0)
                {
                    foreach (var item in Input.RoleIds)
                    {
                        UserRoles ur = new UserRoles();
                        ur.CreateTime = DateTime.Now;
                        ur.RoleId = int.Parse(item);
                        ur.UpdateTime = DateTime.Now;
                        ur.UserId = Input.UserId;
                        listUserRoles.Add(ur);
                    }

                    await _userRolesRepository.InsertAsync(listUserRoles);
                }

                await _unitOfWork.SaveChangesAsync();
                return Result.Successed("设置成功!");

            }
            catch (Exception ex)
            {
                _logger.LogError("保存用户角色异常", ex);
                throw;
            }
        }

        /// <summary>
        /// 获取用户角色id集合
        /// </summary>
        /// <param name="Input"></param>
        /// <returns></returns>
        public async Task<List<string>> GetUserBandRoles(int UserId)
        {
            try
            {
                var userRoles = await _userRolesRepository.GetListAsync(n => n.UserId == UserId);

                return userRoles?.Select(n => n.RoleId.ToString()).ToList();

            }
            catch (Exception ex)
            {
                _logger.LogError("获取用户角色id集合异常", ex);
                throw;
            }
        }




        /// <summary>
        /// 获取角色菜单id集合
        /// </summary>
        /// <param name="Input"></param>
        /// <returns></returns>
        public async Task<List<string>> GetRoleMenuIds(int RoleId)
        {
            try
            {

                var roleMenus = await _rolesMenusRepository.GetListAsync(n => n.RoleId == RoleId && n.MenuType == 3);

                return roleMenus?.Select(n => n.MenuId.ToString()).ToList();

            }
            catch (Exception ex)
            {
                _logger.LogError("获取角色菜单id集合异常", ex);
                throw;
            }
        }




        /// <summary>
        /// 保存角色菜单
        /// </summary>
        /// <param name="Input"></param>
        /// <returns></returns>
        public async Task<Result> BandRoleMenus(BandRoleMenusInput Input)
        { 
            try
            {  

                var existsRoles = await _rolesMenusRepository.GetListAsync(n => n.RoleId == Input.RoleId);
              await _rolesMenusRepository.DeleteAsync(existsRoles);

                List<RoleMenus> listRoleMenus = new List<RoleMenus>();

                if (Input.Items != null && Input.Items.Count != 0)
                {
                    foreach (var item in Input.Items)
                    {
                        RoleMenus ur = new RoleMenus();
                        ur.CreateTime = DateTime.Now;
                        ur.RoleId = Input.RoleId;
                        ur.UpdateTime = DateTime.Now;
                        ur.MenuId = item.Id;
                        ur.MenuType = item.MenuType;
                        listRoleMenus.Add(ur);
                    }

                    await _rolesMenusRepository.InsertAsync(listRoleMenus);
                }

                await _unitOfWork.SaveChangesAsync();
                return Result.Successed("设置成功!");

            }
            catch (Exception ex)
            {
                _logger.LogError("保存角色菜单异常", ex);
                throw;
            }
        }



        /// <summary>
        /// 获取用户可访问的页面
        /// </summary>
        /// <param name="UserId"></param>
        /// <returns></returns>
        public async Task<List<string>> GetUserMenuIds()
        { 
            try
            { 
                int CurrentUserId = _applicationUser.UserId; 
                IEnumerable<GetUserMenuIdsOutput> list = await _unitOfWork.FromSqlAsync<GetUserMenuIdsOutput>($@"select  b.MenuId from user_roles a
                            join role_menus b on a.RoleId=b.RoleId
                            where b.MenuType in (1,2) and a.UserId={CurrentUserId} ");
                return list?.Select(n => n.MenuId).ToList();

            }
            catch (Exception ex)
            {
                _logger.LogError("获取用户可访问的页面异常", ex);
                throw;
            }
        }


        /// <summary>
        /// 获取用户可访问的页面按钮
        /// </summary>
        /// <param name="UserId"></param>
        /// <returns></returns>
        public async Task<List<string>> GetUserMenuButtonIds()
        { 
            try
            { 
                int CurrentUserId = _applicationUser.UserId; 
                IEnumerable<GetUserMenuIdsOutput> list = await _unitOfWork.FromSqlAsync<GetUserMenuIdsOutput>($@"select  b.MenuId from user_roles a
                            join role_menus b on a.RoleId=b.RoleId
                            where b.MenuType =3 and a.UserId={CurrentUserId} ");
                return list?.Select(n => n.MenuId).ToList();

            }
            catch (Exception ex)
            {
                _logger.LogError("获取用户可访问的页面按钮异常", ex);
                throw;
            }
        }
    }
}
